#include <iostream>
#include "simulator/tools/bitTools.h"
#include "dspSimulator/dspSimulator/dspSimulator.h"

using namespace dspsimulator;
using namespace simulator;

int main() {
    auto dsp_machine = std::make_shared<DspMachine>();
    std::shared_ptr<LLVMJit> llvmJit = std::make_shared<LLVMJit>();
    const char *filePath = "/home/zengao/Desktop/dsp-sim/for.out";
    std::shared_ptr<simulator::ELF32Loader> elfLoader = std::make_shared<simulator::ELF32Loader>(filePath);

    auto dsp_simulator = std::make_shared<dspsimulator::DSPSimulator>(dsp_machine, llvmJit, elfLoader);

    std::string pc_name = get_reg_name(dspsimulator::RegKind::PC);
    u32 pc = 0x85A4;
    dsp_machine->registers()->get_reg32(pc_name)->set_data(pc);
    auto memory = dsp_machine->mmu()->memory();
    // 0C26 MVK .L1  0,A0
    {
        std::vector<u8> mvk = {0x26, 0x0c};
        memory->write(mvk, pc);
        pc += 2;
    }
//    // 0C26 MVK .L1  1,A0
//    {
//        std::vector<u8> mvk = {0x26, 0x0c};
//        memory->write(mvk, pc);
//        pc += 2;
//    }
    // 24A6 MVK .L1 1, A1
    {
        std::vector<u8> mvk = {0xa6, 0x24};
        memory->write(mvk, pc);
        pc += 2;
    }
    // 9003E000 [!A1] SPLOOPW 1
    {
        std::vector<u8> sploopw = {0x00, 0xe0, 0x03, 0x90};
        memory->write(sploopw, pc);
        pc += 4;
    }
    // 04202058 ADD .L1 1, A8,A8
    {
        std::vector<u8> add = {0x58, 0x20, 0x20, 0x04};
        memory->write(add, pc);
        pc += 4;
    }
    // 0c6E NOP 1
    {
        std::vector<u8> nop = {0x6e, 0x0c};
        memory->write(nop, pc);
        pc += 2;
    }
    // 78ee SUB .S1,A1,1,A1
    {
        std::vector<u8> sub = {0xee, 0x78};
        memory->write(sub, pc);
        pc += 2;
    }
    // 2C6E NOP 2
    {
        std::vector<u8> nop = {0x6e,0x2c};
        memory->write(nop,pc);
        pc += 2;
    }
    // 5147 MV .L2x A2,B2
    {
        std::vector<u8> mv = {0x47, 0x51};
        memory->write(mv, pc);
        pc += 2;
    }
    // 000034001 SPKERNEL 0, 0
    {
        std::vector<u8> spkernel = {0x01,0x40,0x03,0x00};
        memory->write(spkernel, pc);
        pc += 4;
    }
    // .fphead E6608000
    {
        std::vector<u8> headword = {0x00, 0x80, 0x60, 0xe6};
        std::cout << "headword " << common::dec_to_hex(pc) << std::endl;
        memory->write(headword, pc);
        pc += 4;
    }
    // 04a001a0 MV .S1 A8, A9
    {
        std::vector<u8> mv = {0xa0, 0x01, 0xa0, 0x04};
        memory->write(mv, pc);
        pc += 4;
    }
    // 04202058   ADD.L1 1,A8,A8
    {
        std::vector<u8> add = {0x58, 0x20, 0x20, 0x04};
        memory->write(add, pc);
        pc += 4;
    }
    // 04202058   ADD.L1 1,A8,A8
    {
        std::vector<u8> add = {0x58, 0x20, 0x20, 0x04};
        memory->write(add, pc);
        pc += 4;
    }
    // 00000000 NOP
    {
        std::vector<u8> nop = {0x00, 0x00, 0x00, 0x00};
        memory->write(nop, pc);
        pc += 4;
    }
    // 00000000 NOP
    {
        std::vector<u8> nop = {0x00, 0x00, 0x00, 0x00};
        memory->write(nop, pc);
        pc += 4;
    }
    // 00000000 NOP
    {
        std::vector<u8> nop = {0x00, 0x00, 0x00, 0x00};
        memory->write(nop, pc);
        pc += 4;
    }
    dsp_simulator->run();
}